#! /usr/bin/env python   
# -*- coding: utf-8 -*-
# 
from flask import Flask, request, session, g, redirect, url_for, abort, \
     render_template, flash, request_started
from flask_cache import Cache
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
import time
import urllib, hashlib

from model import Model
from config import AppConfig
from controller import Book, User, Account

app = Flask(__name__)
app.config.from_object(AppConfig)
app.secret_key = 'drTewds232$3'

#cache = Cache(app,config={'CACHE_TYPE': 'filesystem'})
cache = Cache(app, config=app.config['CACHE'])

def init_request(sender, **extra):
    get_db()

    g.currenttime = time.time()
    if 'user' not in session:
        g.user = None
    else:
        g.user = session['user']

request_started.connect(init_request, app)

@app.route('/')
@cache.cached(timeout=60,key_prefix='flask:home:%s')
def home():
    return Book.home()

# Swordsman 剑客、武侠
# Supernatural 超自然的
# Time-Travel 穿越
# Science-Fiction 科幻
# Reincarnation 重生轮回
# Urban 都市
# Ancient 古代
# Tanbi 耽美
@app.route('/classify/<type>')
@cache.cached(timeout=3600,key_prefix='flask:classify:%s')
def classify(type):
    return Book.classify(type)

@app.route('/book/<int:id>')
@cache.cached(timeout=3600,key_prefix='flask:book:%s')
def book(id):
    return Book.index(id)

@app.route('/book/<int:book_id>/<int:chapter_id>')
@cache.cached(timeout=2592000,key_prefix='flask:chapter:%s')
def book_chapter(book_id, chapter_id):
    return Book.chapter(book_id, chapter_id)

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        return User.do_register(request)
    else:
        return render_template('register.html', error={}, uform={})

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        return User.do_login(request)
    else:
        return render_template('login.html', error={}, uform={})

@app.route('/logout')
def logout():
    #flash('You were successfully logout')
    session.pop('user', None)
    url = request.environ.get('HTTP_REFERER', '/')
    return redirect(url)

@app.route('/account')
def account():
    try:
        account = Account()
        return account.index(request)
    except Exception as e:
        flash('%s' % str(e), 'error')
        return redirect(url_for('login'))

@app.route('/account/favorite', methods=['GET', 'POST'])
def favorite():
    try:
        account = Account()
    except Exception as e:
        flash('%s' % str(e), 'error')
        return redirect(url_for('login'))

    if request.method == 'POST':
        return account.do_favorite(request)
    else:
        return account.favorite(request)

@app.route('/account/read_history')
def read_history():
    try:
        account = Account()
    except Exception as e:
        flash('%s' % str(e), 'error')
        return redirect(url_for('login'))

    return account.read_history(request)

@app.route('/account/add_comment', methods=['POST'])
def add_comment():
    try:
        account = Account()
    except Exception as e:
        flash('%s' % str(e), 'error')

        url = request.environ.get('HTTP_REFERER', '/')
        return redirect(url)

    return account.add_comment(request)

@app.route('/account/my_comments')
def my_comments():
    try:
        account = Account()
    except Exception as e:
        flash('%s' % str(e), 'error')
        return redirect(url_for('login'))

    return account.my_comments(request)

@app.route('/account/change_password', methods=['GET', 'POST'])
def change_password():
    try:
        account = Account()
    except Exception as e:
        flash('%s' % str(e), 'error')
        return redirect(url_for('login'))

    if request.method == 'POST':
        return account.change_password(request)
    else:
        return render_template('account_change_password.html', error={})

@app.teardown_appcontext
def close_db(error):
    """Closes the database again at the end of the request."""
    if hasattr(g, 'db'):
        g.db.close()

@app.template_filter('decode')
def decode(s, start='UTF-8'):
    return s.decode(start)

@app.template_filter('strftime')
def strftime(timeStamp, formats="%B %d, %Y at %I:%M %p"):
    timeArray = time.localtime(timeStamp)
    return time.strftime(formats, timeArray)

@app.template_filter('formattime')
def strftime(timeStamp, formats="%Y-%m-%d %H:%M:%S"):
    timeArray = time.localtime(timeStamp)
    return time.strftime(formats, timeArray)

@app.template_filter('get_last_chapter')
def get_last_chapter(book_id):
    chapter = g.db.find('chapter', {'book_id':book_id}, 'page DESC')
    return '<a href="%s">%s</a>' % (url_for('book_chapter', book_id=book_id, chapter_id=chapter['id']), chapter['en_name'])

@app.template_filter('avatarimage')
def avatarimage(email, size=48):
    default = url_for('static', filename='default.png', _external=True)
    default = 'http://lnpan.b0.upaiyun.com/uploads/default2.png'
    gravatar_url = "https://www.gravatar.com/avatar/" + hashlib.md5(email.lower()).hexdigest() + "?"
    gravatar_url += urllib.urlencode({'d':default, 's':str(size)})
    return gravatar_url

def connect_db():
    """Connects to the specific database."""
    model = Model(app.config['DATABASE'])
    return model

def connect_orm_db():
    engine = create_engine(app.config['DATABASE_STRING'], echo=True)

    # 创建会话类
    DB_Session = sessionmaker(bind=engine)

    # 创建会话对象
    session = DB_Session()
    return session
    
def get_db():
    """Opens a new database connection if there is none yet for the
    current application context.
    """
    if not hasattr(g, 'db'):
        g.db = connect_db()
    return g.db

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)
